package metrics

import "git.cloud.inspur.com/ichain/ichain-sdk-go/thirdparty/ichain/common/metrics"

var (
	// for now, only chain clients require metrics tracking. TODO: update to generalize metrics for other client types if needed.
	queriesReceived = metrics.CounterOpts{
		Namespace:    "chain",
		Name:         "queries_received",
		Help:         "The number of chain client queries received.",
		LabelNames:   []string{"contract", "Fcn"},
		StatsdFormat: "%{#fqname}.%{type}.%{chain}.%{query}",
	}
	queriesFailed = metrics.CounterOpts{
		Namespace:    "chain",
		Name:         "queries_failed",
		Help:         "The number of chain client queries that failed (timeouts excluded).",
		LabelNames:   []string{"contract", "Fcn", "fail"},
		StatsdFormat: "%{#fqname}.%{type}.%{chain}.%{query}.%{fail}",
	}
	queryTimeouts = metrics.CounterOpts{
		Namespace:    "chain",
		Name:         "query_timeouts",
		Help:         "The number of chain queries that have failed due to time out.",
		LabelNames:   []string{"contract", "Fcn", "fail"},
		StatsdFormat: "%{#fqname}.%{type}.%{chain}.%{query}.%{timeout}",
	}
	queryDuration = metrics.HistogramOpts{
		Namespace:    "chain",
		Name:         "query_duration",
		Help:         "The time to complete chain client query.",
		LabelNames:   []string{"contract", "Fcn"},
		StatsdFormat: "%{#fqname}.%{type}.%{chain}.%{query}",
	}
	executionsReceived = metrics.CounterOpts{
		Namespace:    "chain",
		Name:         "executions_received",
		Help:         "The number of chain client executions received.",
		LabelNames:   []string{"contract", "Fcn"},
		StatsdFormat: "%{#fqname}.%{type}.%{chain}.%{execute}",
	}
	executionsFailed = metrics.CounterOpts{
		Namespace:    "chain",
		Name:         "executions_failed",
		Help:         "The number of chain client executions that failed (timeouts excluded).",
		LabelNames:   []string{"contract", "Fcn", "fail"},
		StatsdFormat: "%{#fqname}.%{type}.%{chain}.%{execute}.%{fail}",
	}
	executionTimeouts = metrics.CounterOpts{
		Namespace:    "chain",
		Name:         "execution_timeouts",
		Help:         "The number of chain executions that have failed due to time out.",
		LabelNames:   []string{"contract", "Fcn", "fail"},
		StatsdFormat: "%{#fqname}.%{type}.%{chain}.%{execute}.%{timeout}",
	}
	executionDuration = metrics.HistogramOpts{
		Namespace:    "chain",
		Name:         "execution_duration",
		Help:         "The time to complete chain client execution.",
		LabelNames:   []string{"contract", "Fcn"},
		StatsdFormat: "%{#fqname}.%{type}.%{chain}.%{execution}",
	}
)

// ClientMetrics contains the metrics used in the (chain) client
type ClientMetrics struct {
	QueriesReceived    metrics.Counter
	QueriesFailed      metrics.Counter
	QueryDuration      metrics.Histogram
	QueryTimeouts      metrics.Counter
	ExecutionsReceived metrics.Counter
	ExecutionsFailed   metrics.Counter
	ExecutionDuration  metrics.Histogram
	ExecutionTimeouts  metrics.Counter
}

// NewClientMetrics builds a new instance of ClientMetrics
func NewClientMetrics(p metrics.Provider) *ClientMetrics {
	return &ClientMetrics{
		QueriesReceived:    p.NewCounter(queriesReceived),
		QueriesFailed:      p.NewCounter(queriesFailed),
		QueryDuration:      p.NewHistogram(queryDuration),
		QueryTimeouts:      p.NewCounter(queryTimeouts),
		ExecutionsReceived: p.NewCounter(executionsReceived),
		ExecutionsFailed:   p.NewCounter(executionsFailed),
		ExecutionDuration:  p.NewHistogram(executionDuration),
		ExecutionTimeouts:  p.NewCounter(executionTimeouts),
	}
}
